﻿using System;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Xml;
using Dados.ConexaoSQL;
using System.Collections;
using EFITransmissao.Entidade;
using System.Collections.Generic;

namespace Dados.ConexaoSQL
{
    public class MSSQLDataAccess //: IDataAccess
    {
        private SqlConnection conexao;

        #region Contrutores

        /// <summary>
        /// Inicializa a classe de conexão com Banco de Dados.
        /// </summary>
        public MSSQLDataAccess()
        {
            string stringconexao = @"Data Source=SFSGP01;Initial Catalog=Leituras;Persist Security Info=True;User ID='coleta';Password='coleta'";
            
            conexao = new SqlConnection(stringconexao);
        }

        /// <summary>
        /// Inicializa a classe de conexão com Banco de Dados.
        /// </summary>
        /// <param name="stringConexao">stringConexao</param>
        public MSSQLDataAccess(string stringConexao)
        {
            string stringconexao = @"Data Source=SFSGP01;Initial Catalog=Leituras;Persist Security Info=True;User ID='coleta';Password='coleta'";

            conexao = new SqlConnection(stringconexao);
        }

        /// <summary>
        /// Inicializa a classe de conexão com Banco de Dados.
        /// </summary>
        /// <param name="conexao">conexao</param>
        /// <param name="stringConexao">stringConexao</param>
        public MSSQLDataAccess(SqlConnection conexao, string stringConexao)
        {
            string stringconexao = @"Data Source=SFSGP01;Initial Catalog=Leituras;Persist Security Info=True;User ID='coleta';Password='coleta'";

            conexao = new SqlConnection(stringconexao);
        }

        /// <summary>
        /// Inicializa a classe de conexão com Banco de Dados.
        /// </summary>
        /// <param name="trans">MSDataAccess</param>
        public MSSQLDataAccess(ref MSTransacao trans)
        {
            conexao = null;
        }

        #endregion

        #region AbrirConexao

        /// <summary>
        /// Abre a conexão com o Banco.
        /// </summary>
        public void AbrirConexao()
        {
            conexao.Open();
        }

        #endregion

        #region FecharConexao

        /// <summary>
        /// Fecha a conexão com o Banco.
        /// </summary>
        public void FecharConexao()
        {
            conexao.Close();
        }

        #endregion

        #region ExecutaConsulta

        /// <summary>
        /// Executa uma consulta a partir de um comando registrado e repassado.
        /// </summary>
        /// <param name="query">Id do comando registrado</param>
        /// <param name="htParametros">Parâmetros utilizados pela consulta</param>
        /// <returns>DataTable</returns>
        public DataTable ExecutaConsultaStatusLeituraDisponivel(string query, int matricula)
        {
            try
            {
                AbrirConexao();

                DataTable dtt = new DataTable();
                Querys qry = new Querys();

                string sql = qry.dbQuery(query);
                
                SqlCommand comando = new SqlCommand(sql, this.conexao);
                comando.Parameters.Add(new SqlParameter("@matricula", SqlDbType.Int)).Value = matricula;
                
                try
                {
                    SqlDataAdapter adapter = new SqlDataAdapter(comando);
                    adapter.Fill(dtt);
                }
                catch (Exception ex)
                {                    
                    query = ex.Message;
                }

                return dtt;
            }
            finally
            {
                FecharConexao();
            }
        }

        public DataTable ExecutaConsulta(string query, Hashtable htParametros)
        {
            try
            {
                AbrirConexao();

                DataTable dtt = new DataTable();
                Querys qry = new Querys();

                string sql = qry.dbQuery(query);

                SqlCommand comando = new SqlCommand(sql, this.conexao);
                if (htParametros != null)
                {
                    foreach (object chave in htParametros.Keys)
                    {
                        comando.Parameters.AddWithValue(chave.ToString(), htParametros[chave].GetType());
                        comando.Parameters[chave.ToString()].Value = htParametros[chave];
                    }
                }

                try
                {
                    SqlDataAdapter adapter = new SqlDataAdapter(comando);
                    adapter.Fill(dtt);
                }
                catch (Exception ex)
                {
                    query = ex.Message;
                }

                return dtt;
            }
            finally
            {
                FecharConexao();
            }
        }

        public void ExecutaAtualizacaoObjeto(string query, EFITransmissao.Entidade.Roteiro obj)
        {
            try
            {
                AbrirConexao();

                Querys qry = new Querys();
                string sql = qry.dbQuery(query);

                SqlCommand comando = new SqlCommand(sql, this.conexao);
                comando.Parameters.Add(new SqlParameter("@mat", SqlDbType.NVarChar)).Value = obj.Matricula;
                comando.Parameters.Add(new SqlParameter("@remessa", SqlDbType.Int)).Value = obj.Remessa;
                comando.Parameters.Add(new SqlParameter("@mesFat", SqlDbType.NVarChar)).Value = obj.MesFat;

                comando.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                FecharConexao();
            }
        }

        public void ExecutaAtualizacaoNovoMedidor(string query, EFITransmissao.Entidade.NovoMedidor obj)
        {
            try
            {
                AbrirConexao();

                Querys qry = new Querys();
                string sql = qry.dbQuery(query);

                SqlCommand comando = new SqlCommand(sql, this.conexao);
                comando.Parameters.Add(new SqlParameter("@uc", SqlDbType.NVarChar)).Value = obj.Uc;
                comando.Parameters.Add(new SqlParameter("@medLocal", SqlDbType.NVarChar)).Value = obj.MedidorLocal;
                comando.Parameters.Add(new SqlParameter("@novoMed", SqlDbType.NVarChar)).Value = obj.NovMedidor;
                comando.Parameters.Add(new SqlParameter("@matricula", SqlDbType.NVarChar)).Value = obj.Matricula;
                comando.Parameters.Add(new SqlParameter("@leiturista", SqlDbType.NVarChar)).Value = obj.Leiturista;
                comando.Parameters.Add(new SqlParameter("@rota", SqlDbType.NVarChar)).Value = obj.Rota;
                comando.Parameters.Add(new SqlParameter("@mesFat", SqlDbType.NVarChar)).Value = obj.MesFat;                
                comando.Parameters.Add(new SqlParameter("@marca", SqlDbType.NVarChar)).Value = obj.Marca;
                comando.Parameters.Add(new SqlParameter("@modelo", SqlDbType.NVarChar)).Value = obj.Modelo;
                comando.Parameters.Add(new SqlParameter("@idFoto", SqlDbType.NVarChar)).Value = obj.IdFoto;
                if (obj.IdFoto != null)
                    comando.Parameters.Add(new SqlParameter("@Foto", SqlDbType.Image)).Value = obj.Foto;
                else
                    comando.Parameters.Add(new SqlParameter("@Foto", SqlDbType.NVarChar)).Value = DBNull.Value;

                comando.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                FecharConexao();
            }
        }

        #endregion

        #region ExecutaAtualizacao

        /// <summary>
        /// Executa atualização a partir de uma comando registrado.
        /// </summary>
        /// <param name="query">Id do  do comando registrado</param>
        /// <param name="htParametros">Parâmetros utilizados pela consulta</param>
        public void ExecutaAtualizacao(string query, System.Collections.Hashtable htParametros)
        {
            try
            {
                AbrirConexao();

                //string sql = consultaQuery(query);                
                Querys qry = new Querys();

                string sql = qry.dbQuery(query);

                SqlCommand comando = new SqlCommand(sql, this.conexao);

                if (htParametros != null)
                {
                    foreach (object chave in htParametros.Keys)
                    {
                        comando.Parameters.AddWithValue(chave.ToString(), htParametros[chave].GetType());
                        comando.Parameters[chave.ToString()].Value = htParametros[chave];
                    }
                }

                comando.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                //Utilitarios.gravarLog(ex.Message);
                throw ex;
            }
            finally
            {
                FecharConexao();
            }
        }

        public void ExecutaAtualizacao_DesmacaPartesREC_SQL(string query, Roteiro obj)
        {
            try
            {
                AbrirConexao();

                DataTable dtt = new DataTable();
                Querys qry = new Querys();

                string sql = qry.dbQuery(query);

                SqlCommand comando = new SqlCommand(sql, this.conexao);
                comando.Parameters.Add(new SqlParameter("@matricula", SqlDbType.NVarChar)).Value = obj.Matricula;
                comando.Parameters.Add(new SqlParameter("@remessa", SqlDbType.Int)).Value = obj.Remessa;
                comando.Parameters.Add(new SqlParameter("@mesFat", SqlDbType.NVarChar)).Value = obj.MesFat;

                comando.ExecuteNonQuery();
            }
            finally
            {
                FecharConexao();
            }
        }

        public void ExecutaAtualizacao_DesmacaPartesENV_SQL(string query, Roteiro obj)
        {
            try
            {
                AbrirConexao();

                DataTable dtt = new DataTable();
                Querys qry = new Querys();

                string sql = qry.dbQuery(query);

                SqlCommand comando = new SqlCommand(sql, this.conexao);
                comando.Parameters.Add(new SqlParameter("@matricula", SqlDbType.NVarChar)).Value = obj.Matricula;
                comando.Parameters.Add(new SqlParameter("@remessa", SqlDbType.Int)).Value = obj.Remessa;
                comando.Parameters.Add(new SqlParameter("@mesFat", SqlDbType.NVarChar)).Value = obj.MesFat;

                comando.ExecuteNonQuery();
            }
            finally
            {
                FecharConexao();
            }
        }

        public void ExecutaAtualizacao_TrocaRota(string query, IList<TrocaRota> lst)
        {
            try
            {
                AbrirConexao();

                DataTable dtt = new DataTable();
                Querys qry = new Querys();

                string sql = qry.dbQuery(query);
               
                foreach (var item in lst)
                {
                    SqlCommand comando = new SqlCommand(sql, this.conexao);
                    comando.Parameters.Add(new SqlParameter("@uc", SqlDbType.Int)).Value = item.Uc;
                    comando.Parameters.Add(new SqlParameter("@grupoFat", SqlDbType.Int)).Value = item.IdGrupoFat;
                    comando.Parameters.Add(new SqlParameter("@daRota", SqlDbType.NVarChar)).Value = item.DaRota;
                    comando.Parameters.Add(new SqlParameter("@paraRota", SqlDbType.NVarChar)).Value = item.ParaRota;
                    comando.Parameters.Add(new SqlParameter("@matricula", SqlDbType.Int)).Value = item.Matricula;
                    comando.Parameters.Add(new SqlParameter("@leiturista", SqlDbType.NVarChar)).Value = item.Leiturista;
                    comando.Parameters.Add(new SqlParameter("@mes", SqlDbType.NVarChar)).Value = item.Mes;

                    comando.ExecuteNonQuery();
                }
                
            }
            finally
            {
                FecharConexao();
            }
        }

        #endregion

        #region ExecutaConsultaTransacional

        /// <summary>
        /// Executa uma consulta a partir de um comando registrado e repassado.
        /// </summary>
        /// <param name="query">Id  do comando registrado</param>
        /// <param name="htParametros">Parâmetros utilizados pela consulta</param>
        /// <returns>DataTable</returns>
        public DataTable ExecutaConsultaTransacional(ref MSTransacao trans, string query, System.Collections.Hashtable htParametros)
        {
            DataTable dtt = new DataTable();

            try
            {
                string sql = consultaQuery(query);

                SqlCommand comando = new SqlCommand(sql, trans.Conexao);
                comando.Transaction = trans.Transacao;

                if (htParametros != null)
                {
                    foreach (object chave in htParametros.Keys)
                    {
                        comando.Parameters.AddWithValue(chave.ToString(), htParametros[chave].GetType());
                        comando.Parameters[chave.ToString()].Value = htParametros[chave];
                    }
                }
                SqlDataAdapter adapter = new SqlDataAdapter(comando);
                adapter.Fill(dtt);
            }
            catch (Exception ex)
            {
                //Utilitarios.gravarLog(ex.Message);
                query = ex.Message;
            }

            return dtt;
        }

        #endregion

        #region ExecutaAtualizacaoTransacional

        /// <summary>
        /// Executa atualização a partir de uma comando registrado.
        /// </summary>
        /// <param name="query">Id do  do comando registrado</param>
        /// <param name="htParametros">Parâmetros utilizados pela consulta</param>
        public void ExecutaAtualizacaoTransacional(ref MSTransacao trans, string query, System.Collections.Hashtable htParametros)
        {
            try
            {
                string sql = consultaQuery(query);

                SqlCommand comando = new SqlCommand(sql, trans.Conexao);
                comando.Transaction = trans.Transacao;

                foreach (object chave in htParametros.Keys)
                {
                    comando.Parameters.AddWithValue(chave.ToString(), htParametros[chave].GetType());
                    comando.Parameters[chave.ToString()].Value = htParametros[chave];
                }

                comando.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                //Utilitarios.gravarLog(ex.Message);
                throw ex;
            }
        }

        #endregion

        #region consultaQuery XML

        /// <summary>
        /// Consulta string de comando SQL registrada no MapQuery.
        /// </summary>
        /// <param name="id">Id do  do comando registrado</param>
        /// <returns>Comando SQL</returns>
        private string consultaQuery(string id)
        {
            XmlDocument xml = new XmlDocument();

            xml.Load(@".\MapQuery.xml");

            XmlNodeList queries = xml.SelectNodes("Queries/Query");
            string strQuery = null;
            string idQuery = null;

            foreach (XmlNode query in queries)
            {
                idQuery = query.Attributes["Id"].InnerText;

                if (idQuery == id)
                {
                    strQuery = query.InnerText;
                    break;
                }
            }

            return strQuery;
        }

        #endregion

    }
}
